暫存器是 CPU 運算時暫時儲存數據的地方,不同的 CPU 架構會有不同的設計,暫存器也會有不同的數量與用法,更甚至指令與底層的機械碼會不一樣,所以在進行底層開發時通常會建議去查閱一下相關的官方文檔,例如 Intel 的軟體開發手冊,在其 Volume 1 的 3-3 頁就有關於暫存器的圖解。
其中就有常見的通用暫存器、區段暫存器、指標暫存器、旗標暫存器。
就現在的架構來說至少有 16 個通用暫存器,每個通用暫存器又可以依照它的 bit 數不同而有不同的名稱,大家可以注意到,AX、BX、CX、DX 在 8 bit 時可以有 H 與 L 的命名,H為高八位位元,L 為低八位位元,具體可以看下圖。
雖然不同 bit 數有不同名字,甚至也能作為運算子來作運算,但他們在物理上是同一顆暫存器,因此如果改變了 AH 的數值,也就會連帶改變到AX、EAX、RAX的數值。
有 CS、DS、SS、ES、FS、GS 六個暫存器,主要的功用是指向不同的記憶體區段,CS ( Code-Segment )、DS ( Data-Segment )、SS ( Stack Segment )、而 ES、FS、GS 也是 Data-Segment ,但這三個是選擇性使用。
有 EIP、EBP、ESP、ESI、EDI ,
EIP 指向目前即將執行的指令的位址
EBP 與 ESP 分別指向目前 Stack 的 frame 的頭跟尾,也就是目前的 frame 的第一筆資料的位置跟最後一筆資料的位置。
有 EFLAGS ,為 32 bit 的暫存器,使用其中的 bit 去代表不同的狀態,以控制程序的進行。也可以拓展至 64 位元,但拓展出的 32 位元皆保留。
可以注意到 EFLAG 使用其中的 bit 來當作它的狀態標記或是控制標記,
名稱 | 作用 |
---|---|
CF | 進位旗標,表示最高位元有無進位借位 |
PF | 奇偶旗標,表示低八位元 1 的數量 |
AF | 輔助進位旗標,表示第 4 位元有無進位借位 |
ZF | 零旗標,表示運算結果是否為零 |
SF | 符號旗標,表示正負數 |
OF | 溢位旗標,表示有無溢位 |
名稱 | 作用 |
---|---|
TF | 單步旗標,debug 用,表示一次執行一個指令 |
IF | 中斷旗標,表示可否接受外部中斷 |
DF | 方向旗標,處理字串用,表示由高地址到低地址或相反 |
名稱 | 作用 |
---|---|
IOPL | I/O 特權旗標,若當前程式的特權級別小於等於 IOPL ,則可執行 I/O 指令 |
NT | 巢狀工作旗標,,若為 1 ,用 Stack 中的值恢復 EFLAG 、CS 和 EIP ,並返回工作 |
RF | 重啟旗標,若為 0,則接受除錯異常 |
VM | 虛擬 8086 模式,若為 1,則允許在保護模式下執行真實模式的程式 |
想進一步了解系統暫存器中的旗標的作用,可以到x86-EFLAGS暫存器詳解瀏覽。
題外
根據這篇討論拿來運算的暫存器總共有 40 個。但又根據這篇文章計算指出,若把不同 bit 的暫存器也計算為一個,再加上零零總總各種不同功能的暫存器進去的話大約會有 557 個暫存器。
參考資料 :
EFLAG - 百科知識
80x86 系統暫存器及系統指令
Intel 80386 Reference Programmer's Manual Table of Contents at 4.1 System Registers
86-EFLAGS暫存器詳解
FLAGS register - Wiki